[Day16] 但是歷史正文上的符號真是複雜難懂啊...
哈囉各位晚安,今天要介紹的是符號(Symbol)!
大家對符號應該不陌生,畢竟每天傳訊息都會用到啊!
????????????????????? 啊不是這是表情符號...
在 Ruby 裡,符號是一種「帶有名字的物件」。
會用冒號 :
開頭來表示符號,同時符號也具有唯一性(immutable),一旦被建立後就無法改變。
最容易看到符號的地方就是在雜湊(Hash)了!我們經常使用符號來表示雜湊裡的鍵(key):
hash = {
:cat => 1,
:dog => 2,
:man => 3
}
也可以寫成這樣:
hash = {
cat: 1,
dog: 2,
man: 3
}
另外,符號也可以拿來指稱方法:
def call_me
puts "打電話給我!"
end
=> :call_me
首先,雖然看起來和變數超級像,但符號它不是「變數」而是「值」。
如果我們把符號當作變數一樣在用:
# 把字串指定給符號
:name = 1
=> SyntaxError ((irb):15: syntax error, unexpected '=', expecting end-of-input)
:name = 1
# 把字串指定給符號
:name = "Hi"
=> SyntaxError ((irb):16: syntax error, unexpected '=', expecting `end')
:name = "Hi"
Ruby 會告訴你這樣的語法是錯誤的!因為按照正常的程式邏輯,我們不能把一個值指定給另一個值。
任何一個符號都有著自己的記憶體位置,並始終指向那個位置,因此會較省記憶體。比起字串,用符號來當作雜湊的鍵(key),存取效能的表現會更好。
為什麼存取效能更好?原因是當程式在比較兩個物件時,若是符號,程式會直接比對 object_id 是否相同。然而在比對字串時,則是會從第一個字元開始,逐一比對是否相同。因此,在效能上字串的時間複雜度會隨著字元數量增加而提升,但符號就沒有這樣的問題。
接著我們來看看字串和符號的差別:
"hi".object_id
=> 180
"hi".object_id
=> 200
"hi".object_id
=> 220
"hi".object_id
=> 240
:call_me.object_id
=> 2034908
:call_me.object_id
=> 2034908
然而,符號用太多而沒有歸還記憶體時,會出現 記憶體流失(Memory leak) 的問題(簡單來說,是一種在設計上造成的記憶體浪費)
true
、false
、nil
的 object_id 也會變動嗎?數字的 object_id 是固定的,被放在記憶體的奇數位置上。譬如數字 n ,位置就是 2n+1:
1.object_id
=> 3
2.object_id
=> 5
3.object_id
=> 7
5.object_id
=> 11
8.object_id
=> 17
而 true
、false
、nil
則是在記憶體的偶數位置,也是固定的:
true.object_id
=> 20
false.object_id
=> 0
nil.object_id
=> 8
關於 Ruby 的符號今天就介紹到這邊啦!希望之有時間的話能再提一些自己在實際運用上的案例及理解,謝謝大家的觀看!